/*
 * Copyright 2005-2013 rsico. All rights reserved.
 * Support: http://www.rsico.cn
 * License: http://www.rsico.cn/license
 */
package com.rzico.account.plugin.hxBank;

import com.rzico.account.entity.Payment;
import com.rzico.account.service.PaymentService;
import com.rzico.account.service.RefundsService;
import com.rzico.core.entity.SysPlugin;
import com.rzico.core.entity.SysUser;
import com.rzico.core.model.PluginAttribute;
import com.rzico.core.plugin.PaymentPlugin;
import com.rzico.exception.CustomException;
import com.rzico.util.StringUtils;
import com.rzico.util.XMLUtils;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Plugin - 微信支付(普通商户/特约商户)
 * @author rsico Team
 * @version 3.0
 */
@Component("weixinMiniPayPlugin-hx")
@Slf4j
public class WeiXinMiniPayPlugin extends PaymentPlugin {

	public static final String UNIFIED_ORDER_URL = "https://obank.fjhxbank.com/hxPay/upaygate/wechatSmallProgOrderCrt.do";
	public static final String REFUNDS_ORDER_URL = "https://obank.fjhxbank.com/hxPay/upaygate/orderRefund.do";
	public static final String TRADE_QUERY_URL = "https://obank.fjhxbank.com/hxPay/upaygate/orderStatQry.do";


	//商户公钥
	//public static final String merPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsqr9ig6scMgLV5N7lZNNEoWnF+fPMhiapbYxpL7yXuaAxQZeZtjFsr7Na6PeltssZbrroSTiE11xD6KieuWBx3LbbNI9W5KBAzXzS4L2oDyiJMU4nMJODWzhYqVgncAmzcbfazkRibU8OtT1FSXgWpf1b2IMjRfJBJbZzikerifJzaMcAyZJFkg5nzuxjeesDFBKlR+yyLLFhv4hfaOf4eIOBbrOKODWwUkeF0+t9YIDot4I94zfgTVpm5N5uN1ZqKdGv4fja9buW6UkB9PeZvA66M3RIWJ9ev3EK1IlN+NegAzsxmmeEMdzPRBQLQTq1wRip8n2PpNRbpT+/KIOEwIDAQAB";
	//商户私钥
	//public static final String merPrivateKey = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCyqv2KDqxwyAtXk3uVk00ShacX588yGJqltjGkvvJe5oDFBl5m2MWyvs1ro96W2yxluuuhJOITXXEPoqJ65YHHctts0j1bkoEDNfNLgvagPKIkxTicwk4NbOFipWCdwCbNxt9rORGJtTw61PUVJeBal/VvYgyNF8kEltnOKR6uJ8nNoxwDJkkWSDmfO7GN56wMUEqVH7LIssWG/iF9o5/h4g4Fus4o4NbBSR4XT631ggOi3gj3jN+BNWmbk3m43Vmop0a/h+Nr1u5bpSQH095m8DrozdEhYn16/cQrUiU3416ADOzGaZ4Qx3M9EFAtBOrXBGKnyfY+k1FulP78og4TAgMBAAECggEAM7jERN8SlGOUxPlw4VAPE7mVMZptpLbyrd4caPDOASMBTAgX8/X05VXO6cY6fbldFOYTqEahG7IFNN2D48fk1fQuCUajdIroxiEsGUQEWUa0OajORrMJHWHTrVbqrUAe+5sCumt+5DqPAQj9Ge4pEJDFAEWGFKI6ExYIX2IP+6IUtvkkyGZluWaIRcBmuzNBpX4WdR8lxiVCeCnJ3qth2aQoWe58jZkic21TBjhIqBxoVn3cz1qIlmFIkmKqjBLXrfHRnUDXcyBPWMZVdb0vwhB3PAHPmWqRPcxhqCkzUcmhy+gU3DGdLcTBRt7aPdx2waSQpeDRm8RkEAOx2PShoQKBgQDqPwSngHAa+nCwcDWP/pmJf6yiUc7tDxi4i0BQ3mAFxXrfNHoQQumxL0uurQCak61QjDMywqFwP4P2EteTMh7kizsAUCHAqaNFJN4g+ZF8XF0L02tN6hXl8fukUScg5EhShAqGZjLrNNcKi83cyhKyju11iCtKgtqrzAicAtgRxQKBgQDDQqbusAHSyXlGMqGSDCzEdkwqZ9WeMsl8XfielPAml5ln8q28fmuDv3B5rTE+O36olBLomHUEDSakw1w+2GNn/RJ3x7jCyvLplzTtaTlnLdEuzqoWd+CNtPm2N5zo3gluCPAXn6dusq05TtzbK17A+FMhchKdUHKJZqPk7+DV9wKBgCK8+7y3cGif0UxpJ5hWIoDgnUJpLW28emcLx5r2j3jro2AskRmOQsfTAr9BysAhvGcgk4soj/ZshO5eNvgOS8SK3VIbkBXZUmwznnl3aVru+6GAVf51A5BZRX9Fxa68C/mouULbLxvwdx+KQhpHIWS3i4GNkxX2t+UYWgKA7XgdAoGAGTAR5Jxjv9Mph7qkSPi1FarE7Ht0fPHEN/zPQ3Wm/PN1YIlXjAcqy1X4plmHDqYSEqD3R3XTMnCX2Y0x6xFy0Uk+BqGG3encJ/HPbAi01PB+GXGjUz6nguAjjjPiU8/Am6cfgYygxpDZ85iOuN8BXBcschYK/KwR+lN5NOEUucUCgYARkaKqmrf210lx9PWSn2cjF79og7Bjc84sb8Ke97+GUFYMHKLnDyrBgoERG6yS8qjJ6USk2yQitLpZGX3tGiN5B8R/3Rnwt6gApN7hDDUGOKPZOo2trfDAq0HlVPq/GkvO0vxdw714y/9OW3pPF/pE/PZ66L9FAZtW6lZ7lIAN8A==";
	//银行公钥
	//public static final String orgPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAneDijYvxjyKBRulmJc1juOEHHE5LxqgPj9zglht9+yUsXq2pV4C5MQYhozyL8+0H1QAUCv5Sp+M6ITXDn62rwriIYnkyD2ZbJ8pv9N0VQTAE+krAREaCq+JFWvYoqpBlyLeIE+Tgk+TEeymrGciMGfrBquLSCd+CUIGQxcdXBJtD13SuET+NiYPjcScWl6mOltRaPsn8JV04AE416ReXP9tPqIHx7Z860rup9ZBf43JWsKNrSm851PxdddpiCWLMGs8+rNtcc87t1QpyrKs0NCzHMeU+GUeO/1Nd2hSD+mn4/y6awHJfX1c7KpLyH9sSxhWzl58SaZHwrGvHRcQHdQIDAQAB";

	public static final String SUCCESS_CODE = "0000000000";

	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

	@Autowired
	@Lazy
	private PaymentService paymentService;

	@Override
	public String getName() {
		return "海峡银行微信支付(小程序)";
	}

	@Override
	public String getVersion() {
		return "1.0";
	}

	@Override
	public List<PluginAttribute> getAttributeKeys() {
		List<PluginAttribute> data = new ArrayList<>();
		data.add(new PluginAttribute("appid","appid",PluginAttribute.STRING_VALUE));
		data.add(new PluginAttribute("mchid","商户号",PluginAttribute.STRING_VALUE));
		data.add(new PluginAttribute("merPublicKey","商户公钥",PluginAttribute.STRING_VALUE,null,false));
		data.add(new PluginAttribute("merPrivateKey","商户私钥",PluginAttribute.STRING_VALUE,null,false));
		data.add(new PluginAttribute("orgPublicKey","银行公钥",PluginAttribute.STRING_VALUE,null,false));
		data.add(new PluginAttribute("orgVersionCode","银行版本",PluginAttribute.STRING_VALUE,null,false));
		data.add(new PluginAttribute("merVersionCode","商户版本",PluginAttribute.STRING_VALUE,null,false));
		data.add(new PluginAttribute("spbillCreateIp","IP",PluginAttribute.STRING_VALUE,null,false));
		return data;
	}


	/**
	 * 获取用户号
	 * @param sysUser SysUser
	 * @return 获取用户号
	 */
	@Override
	public String getUserId(SysUser sysUser) {
		return sysUser.getWxmId();
	}

	@Override
	public Map<String, Object> trade(SysPlugin sysPlugin,String tradeNo, String description, BigDecimal totalfee, String userId, HttpServletRequest request) {
		log.info(">>>>>>>>>>>>>>>>>>>>>>>>微信小程序支付 start<<<<<<<<<<<<<<<<<<<<<<<<");
		HashMap<String, Object> packageParams = new HashMap<>();
		HashMap<String, Object> finalpackage = new HashMap<>();
		packageParams = buildComm(sysPlugin);
		//接口名称
		packageParams.put("transCode", "wechatSmallProgOrderCrt");
		//商户号
		packageParams.put("merNo", sysPlugin.getAttribute("mchid"));  //wx_mchid

		//商品描述
		description = description.trim();
		if (description.length()>40) {
			packageParams.put("orderRemark", description.substring(0, 40));
		} else {
			packageParams.put("orderRemark", description);
		}
		//商户订单Id
		packageParams.put("merchOrderId", tradeNo);
		//openId
		packageParams.put("openId", userId);
		//子商户公众号id
		packageParams.put("subAppId", sysPlugin.getAttribute("appid"));
		// 这里写的金额为1 分到时修改
		packageParams.put("orderAmt", totalfee);
		//收银员ID，可使用商户号
		packageParams.put("cashierId", sysPlugin.getAttribute("mchid"));
		//aes秘钥字符串
		String aesKey = StringUtils.CreateNoncestr();
		//aes向量字符串
		String aesIv = StringUtils.CreateNoncestr();

		log.info("aesKey=="+ aesKey);
		log.info("aesIv==="+ aesIv);
//		String edKey = aesKey + aesIv;

		try {
			//签名与构造报文
			String postData = signAndContent(sysPlugin,packageParams, aesKey, aesIv, sysPlugin.getAttribute("orgVersionCode"), sysPlugin.getAttribute("merVersionCode"));

			String respStr = post(UNIFIED_ORDER_URL, postData, null);
			HashMap<String,Object> resultMap = XMLUtils.xmlToMap(respStr);

			log.info("微信小程序支付结果: [{}]", respStr);
			String rspCode = (String) resultMap.get("rspCode");
			if (rspCode.equals(SUCCESS_CODE)) {
				//验证签名
				Map<String, Object> verifyMap = verify(sysPlugin,resultMap.get("content").toString(), aesKey, aesIv);
				if (verifyMap.get("verify").toString().equals("true")){
					if (StringUtils.isNotEmpty(verifyMap.get("data").toString())){

						String url = "http://123.com?" + verifyMap.get("data").toString();
						String packages = "prepay_id=" +  QueryStringUtils.getQuery(url,"prepayId");
						finalpackage.put("appId", QueryStringUtils.getQuery(url,"appId"));
						finalpackage.put("timeStamp", QueryStringUtils.getQuery(url,"timeStamp"));
						finalpackage.put("nonceStr", QueryStringUtils.getQuery(url,"nonceStr"));
						finalpackage.put("signType", QueryStringUtils.getQuery(url,"paySignType"));
						finalpackage.put("paySign", QueryStringUtils.getQuery(url,"paySign"));
						finalpackage.put("package", packages);
						finalpackage.put("tranSn", QueryStringUtils.getQuery(url,"orderId"));
						finalpackage.put("return_code", "0000");
					}else{
						log.error("未收到银行返回的content");
						finalpackage.put("return_code", "0003");
						finalpackage.put("error_msg", "未收到银行返回数据");
					}
				}else{
					log.error("交易数据验签失败");
					finalpackage.put("return_code", "0003");
					finalpackage.put("error_msg", "交易数据验签失败");
				}
			}else{
				finalpackage.put("return_code", "0003");
				finalpackage.put("error_msg", resultMap.get("rspMsg"));
			}

		} catch (Exception e) {
			log.info(e.getMessage());
			finalpackage.put("return_code", "9999");
			finalpackage.put("error_msg", "设置异常2");
		}
		log.info("返回参数:"+finalpackage);
		log.info(">>>>>>>>>>>>>>>>>>>>>>>>微信小程序支付 end<<<<<<<<<<<<<<<<<<<<<<<<");
		return finalpackage;

	}



	@Override
	public String getNotifyMessage(HttpServletRequest request) {
//		return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
		return "SUCCESS";
	}

	/**
	 * 申请退款
	 * 目前仅支持全额退款
	 */
	@Override
	public Map<String, Object> refund(SysPlugin sysPlugin, String refundNo, String tradeNo, BigDecimal totalfee, BigDecimal refundfee , HttpServletRequest request) {
		log.info(">>>>>>>>>>>>>>>>小程序退款 start <<<<<<<<<<<<<<<<<<<<<");
		log.info("refundNo======" + refundNo);
		log.info("tradeNo=======" + tradeNo);
		log.info("totalfee======" + totalfee);
		log.info("refundfee=====" + refundfee);
		HashMap<String, Object> finalpackage = new HashMap<String, Object>();
		HashMap<String, Object> paramsMap = new HashMap<String, Object>();

		Payment payment = paymentService.findBySn(tradeNo);

		paramsMap = buildComm(sysPlugin);

		paramsMap.put("transCode", "orderRefund");
		//商户号
		paramsMap.put("merNo", sysPlugin.getAttribute("mchid"));
		//申请退款人员
		paramsMap.put("operaNo", sysPlugin.getAttribute("mchid"));
		//退款授权人员，仅记录
		paramsMap.put("authOperaNo", sysPlugin.getAttribute("mchid"));

		paramsMap.put("oriOrderId", payment.getTranSn());
		//商户订单ID
		paramsMap.put("merchOrderId",refundNo);
		//交易类型（1：支付，2：退款）
		paramsMap.put("refundAmt", refundfee);

		//aes秘钥字符串
		String aesKey = StringUtils.CreateNoncestr();
		//aes向量字符串
		String aesIv = StringUtils.CreateNoncestr();

//		String edKey = aesKey + aesIv;

		try {
			//签名与构造报文
			String postData = signAndContent(sysPlugin,paramsMap, aesKey, aesIv, sysPlugin.getAttribute("orgVersionCode"), sysPlugin.getAttribute("merVersionCode"));

			String respStr = post(REFUNDS_ORDER_URL, postData, null);

			HashMap<String,Object> resultMap = XMLUtils.xmlToMap(respStr);

			log.info("微信小程序退款结果: [{}]", respStr);
			String rspCode = (String) resultMap.get("rspCode");
			if (rspCode.equals(SUCCESS_CODE)) {
				//验证签名
				Map<String, Object> verifyMap = verify(sysPlugin,resultMap.get("content").toString(), aesKey, aesIv);
				if (verifyMap.get("verify").toString().equals("true")) {
					if (StringUtils.isNotEmpty(verifyMap.get("data").toString())) {
						String url = "http://123.com?" + verifyMap.get("data").toString();
						String refundStat = QueryStringUtils.getQuery(url,"refundStat");

						if ("0".equals(refundStat)){
							finalpackage.put("return_code", "0000");
							finalpackage.put("error_msg", "提交成功");
							finalpackage.put("tranSn",  QueryStringUtils.getQuery(url,"orderNo"));
						}else if ("1".equals(refundStat)){
							finalpackage.put("return_code", "0003");
							finalpackage.put("error_msg", "退款失败");
						}else if ("2".equals(refundStat)){
							finalpackage.put("return_code", "0003");
							finalpackage.put("error_msg", "退款处理中");
						}else{
							finalpackage.put("return_code", "0003");
							finalpackage.put("error_msg", resultMap.get("rspMsg").toString());
						}
						return finalpackage;
					}else{
						log.error("退款未收到银行返回的content");
						finalpackage.put("return_code", "0003");
						finalpackage.put("error_msg", "未收到银行返回数据");
					}
				}else{
					log.error("退款数据验签失败");
					finalpackage.put("return_code", "0003");
					finalpackage.put("error_msg", "退款数据验签失败");
				}
			}else{
				finalpackage.put("return_code", "0003");
				finalpackage.put("error_msg", resultMap.get("rspMsg"));
			}
		} catch (Exception e) {
			log.error(e.getMessage());
			finalpackage.put("return_code", "0003");
			finalpackage.put("error_msg","提交银行出错");
		}
		return finalpackage;
	}


	/**
	 * 查询订单的支付结果  0000成功  9999处理中  其他的失败
	 */
	@Override
	public Map<String, Object> tradeQuery(SysPlugin sysPlugin,String tradeNo,String tranSn, HttpServletRequest request) {
		log.info(">>>>>>>>>>>>>>>查询订单的支付结果 start <<<<<<<<<<<<<<<<");
		log.info("tradeNo===" + tradeNo);
		log.info("tranSn====" + tranSn);
		HashMap<String, Object> finalpackage = new HashMap<>();
		HashMap<String, Object> parameterMap = new HashMap<String, Object>();
		parameterMap = buildComm(sysPlugin);

		parameterMap.put("transCode", "orderStatQry");
		//商户号
		parameterMap.put("merNo", sysPlugin.getAttribute("mchid"));
		//商户订单ID
//		parameterMap.put("merchOrderId",tradeNo);
		//平台编码
		parameterMap.put("orderId", tranSn);
		//交易类型（1：支付，2：退款）
		parameterMap.put("optionFlag", 1);
		//aes秘钥字符串
		String aesKey = StringUtils.CreateNoncestr();
		//aes向量字符串
		String aesIv = StringUtils.CreateNoncestr();

//		String edKey = aesKey + aesIv;
		try {
			String postData = signAndContent(sysPlugin,parameterMap, aesKey, aesIv, sysPlugin.getAttribute("orgVersionCode"), sysPlugin.getAttribute("merVersionCode"));
			String respStr = post(TRADE_QUERY_URL, postData, null);
			HashMap<String,Object> resultMap = XMLUtils.xmlToMap(respStr);
			log.info("微信小程序查询订单结果: [{}]", respStr);
			String rspCode = (String) resultMap.get("rspCode");
			if (rspCode.equals(SUCCESS_CODE)) {
				//验证签名
				Map<String, Object> verifyMap = verify(sysPlugin,resultMap.get("content").toString(), aesKey, aesIv);
				if (verifyMap.get("verify").toString().equals("true")) {
					if (StringUtils.isNotEmpty(verifyMap.get("data").toString())) {
						String url = "http://123.com?" + verifyMap.get("data").toString();
						String status = QueryStringUtils.getQuery(url,"orderStat");
						if (status.equals("02")) {
							finalpackage.put("tranSn", QueryStringUtils.getQuery(url,"orderId"));
							finalpackage.put("return_code", "0000");
							finalpackage.put("error_msg", "支付成功");
						}else if (status.equals("11")) {
							finalpackage.put("tranSn",  QueryStringUtils.getQuery(url,"orderId"));
							finalpackage.put("return_code", "0000");
							finalpackage.put("error_msg","退款成功");
						} else if (status.equals("04")) {
							finalpackage.put("return_code", "0001");
							finalpackage.put("error_msg","支付中");
						} else if (status.equals("13")) {
							finalpackage.put("return_code", "0001");
							finalpackage.put("error_msg","退款中");
						} else if (status.equals("01")) {
							finalpackage.put("return_code", "0002");
							finalpackage.put("error_msg","待支付");
						} else if (status.equals("15")) {
							finalpackage.put("return_code", "0002");
							finalpackage.put("error_msg","退款申请");
						} else if (status.equals("05")) {
							finalpackage.put("return_code", "0002");
							finalpackage.put("error_msg","已撤消");
						} else if (status.equals("03")) {
							finalpackage.put("return_code", "0003");
							finalpackage.put("error_msg","支付失败");
						} else if (status.equals("12")) {
							finalpackage.put("return_code", "0003");
							finalpackage.put("error_msg","退款失败");
						} else {
							finalpackage.put("return_code", "0003");
							finalpackage.put("error_msg", (String) resultMap.get("rspMsg"));
						}
					}else{
						log.error("未收到银行返回的content");
						finalpackage.put("return_code", "0003");
						finalpackage.put("error_msg", "未收到银行返回数据");
					}
				}else{
					log.error("查询数据验签失败");
					finalpackage.put("return_code", "0003");
					finalpackage.put("error_msg", "查询数据验签失败");
				}
			} else if (rspCode.equals("BQRP1012")){
				finalpackage.put("return_code", "0003");
				finalpackage.put("error_msg", (String) resultMap.get("rspMsg"));
			}else  {
				finalpackage.put("return_code", "9999");
				finalpackage.put("error_msg", (String) resultMap.get("rspMsg"));
			}
		} catch (Exception e) {
			finalpackage.put("return_code", "9999");
			finalpackage.put("error_msg", "设置异常");
		}
		log.info("查询订单结果: {}", finalpackage);
		return finalpackage;
	}


	@Override
	public Map<String, Object> refundQuery(SysPlugin sysPlugin,String tradeNo,String tranSn, HttpServletRequest request) {
		log.info(">>>>>>>>>>>>>>>小程序退款查询 start <<<<<<<<<<<<<<<<");
		log.info("tradeNo===" + tradeNo);
		log.info("tranSn====" + tranSn);
		HashMap<String, Object> finalpackage = new HashMap<>();
		HashMap<String, Object> parameterMap = new HashMap<String, Object>();
		parameterMap = buildComm(sysPlugin);

		parameterMap.put("transCode", "orderStatQry");
		//商户号
		parameterMap.put("merNo", sysPlugin.getAttribute("mchid"));
		//商户订单ID
//		parameterMap.put("merchOrderId",tradeNo);
		//平台编码
		parameterMap.put("orderId", tranSn);

		//交易类型（1：支付，2：退款）
		parameterMap.put("optionFlag", 2);
		//aes秘钥字符串
		String aesKey = StringUtils.CreateNoncestr();
		//aes向量字符串
		String aesIv = StringUtils.CreateNoncestr();

//		String edKey = aesKey + aesIv;
		try {
			String postData = signAndContent(sysPlugin,parameterMap, aesKey, aesIv, sysPlugin.getAttribute("orgVersionCode"), sysPlugin.getAttribute("merVersionCode"));
			String respStr = post(TRADE_QUERY_URL, postData, null);
			HashMap<String,Object> resultMap = XMLUtils.xmlToMap(respStr);
			log.info("微信小程序查询订单结果: [{}]", respStr);
			String rspCode = (String) resultMap.get("rspCode");
			if (rspCode.equals(SUCCESS_CODE)) {
				//验证签名
				Map<String, Object> verifyMap = verify(sysPlugin,resultMap.get("content").toString(), aesKey, aesIv);
				if (verifyMap.get("verify").toString().equals("true")) {
					if (StringUtils.isNotEmpty(verifyMap.get("data").toString())) {
						String url = "http://123.com?" + verifyMap.get("data").toString();
						String status = QueryStringUtils.getQuery(url, "orderStat");
						if (status.equals("02")) {
							finalpackage.put("tranSn", QueryStringUtils.getQuery(url,"orderId"));
							finalpackage.put("return_code", "0000");
							finalpackage.put("error_msg", "支付成功");
						} else if (status.equals("11")) {
							finalpackage.put("tranSn",  QueryStringUtils.getQuery(url,"orderId"));
							finalpackage.put("return_code", "0000");
							finalpackage.put("error_msg", "退款成功");
						} else if (status.equals("04")) {
							finalpackage.put("return_code", "0001");
							finalpackage.put("error_msg", "支付中");
						} else if (status.equals("13")) {
							finalpackage.put("return_code", "0001");
							finalpackage.put("error_msg", "退款中");
						} else if (status.equals("01")) {
							finalpackage.put("return_code", "0002");
							finalpackage.put("error_msg", "待支付");
						} else if (status.equals("15")) {
							finalpackage.put("return_code", "0002");
							finalpackage.put("error_msg", "退款申请");
						} else if (status.equals("05")) {
							finalpackage.put("return_code", "0002");
							finalpackage.put("error_msg", "已撤消");
						} else if (status.equals("03")) {
							finalpackage.put("return_code", "0003");
							finalpackage.put("error_msg", "支付失败");
						} else if (status.equals("12")) {
							finalpackage.put("return_code", "0003");
							finalpackage.put("error_msg", "退款失败");

						} else {
							finalpackage.put("return_code", "0003");
							finalpackage.put("error_msg", (String) resultMap.get("rspMsg"));
						}
					} else {
						log.error("未收到银行返回的content");
						finalpackage.put("return_code", "0003");
						finalpackage.put("error_msg", "未收到银行返回数据");
					}
				}else if (rspCode.equals("BQRP1012")){
					finalpackage.put("return_code", "0003");
					finalpackage.put("error_msg", (String) resultMap.get("rspMsg"));
				}else{
					log.error("查询数据验签失败");
					finalpackage.put("return_code", "0003");
					finalpackage.put("error_msg", "查询数据验签失败");
				}
			} else  {
				finalpackage.put("return_code", "9999");
				finalpackage.put("error_msg", (String) resultMap.get("rspMsg"));
			}
		} catch (Exception e) {
			finalpackage.put("return_code", "9999");
			finalpackage.put("error_msg", "设置异常");
		}
		log.info("退款查询结果：{}", finalpackage);

		return finalpackage;
	}


	@Override
	public Map<String, Object> verifyNotify(SysPlugin sysPlugin,HttpServletRequest request) {
		log.info(">>>>>>>>>>>>>>>>>>>接收回调通知 start<<<<<<<<<<<<<<<<<<<<");
		HashMap<String, Object> finalpackage = new HashMap<>();
		try {
			HashMap<String, Object> resultMap = new HashMap<String, Object>();
			StringBuffer info = new StringBuffer();
			InputStream in = request.getInputStream();
			BufferedInputStream buf = new BufferedInputStream(in);
			byte[] buffer = new byte[1024];
			int iRead;
			while ((iRead = buf.read(buffer)) != -1) {
				info.append(new String(buffer, 0, iRead, "UTF-8"));
			}
			resultMap = XMLUtils.xmlToMap(info.toString());
			log.info("回调通知:"+info.toString());
			String rspCode = (String) resultMap.get("rspCode");
			if (rspCode.equals(SUCCESS_CODE)) {
				//aes秘钥字符串
				String aesKey = StringUtils.CreateNoncestr();
				//aes向量字符串
				String aesIv = StringUtils.CreateNoncestr();
				//验证签名
				Map<String, Object> verifyMap = verify(sysPlugin,resultMap.get("content").toString(), aesKey, aesIv);
				if (verifyMap.get("verify").toString().equals("true")) {
					if (resultMap.get("notifyCode").toString().equals("SUCCESS")) {
						String url = "http://123.com?" + verifyMap.get("data").toString();
						//商户订单ID
						String merchOrderId = QueryStringUtils.getQuery(url,"merchOrderId");
						//平台ID
						String orderId = QueryStringUtils.getQuery(url,"orderId");
						finalpackage.put("tradeNo", merchOrderId);
						finalpackage.put("tranSn", orderId);
						finalpackage.put("return_code", "0000");
						return finalpackage;
					}
				}
			}

			finalpackage.put("rspCode", "FAIL");
		} catch (Exception e) {
			finalpackage.put("rspCode", "FAIL");
			finalpackage.put("rspMsg", e.getMessage());
		}
		log.info("通知处理结果：{}", finalpackage);
		log.info(">>>>>>>>>>>>>>>>>>>接收回调通知 end<<<<<<<<<<<<<<<<<<<<");
		return finalpackage;
	}



	private HashMap<String, Object> buildComm(SysPlugin sysPlugin){
		HashMap<String, Object> packageParams = new HashMap<>();
		//渠道ID
		packageParams.put("chnlId", "19022022");
		packageParams.put("signType", "RSA");
		packageParams.put("spbillCreateIp", sysPlugin.getAttribute("spbillCreateIp"));
		packageParams.put("reqTime", sdf.format(new Date()));
		//发起方流水号
		packageParams.put("transSeqNo", System.currentTimeMillis());
		return packageParams;
	}


	public String signAndContent(SysPlugin sysPlugin,Map<String, Object> params, String aesKey, String aesIv, String orgSerNum, String merSeNum) throws Exception{
		String str = joinKeyValue(params,"&",true,"sign","signType");
		log.info("待签名字符串:" + str);
		String edkString = aesKey + aesIv;
		String signString = str;

		PublicKey org_publicKey = RSAUtils.string2PublicKey(sysPlugin.getAttribute("orgPublicKey"));
		PrivateKey mer_privateKey = RSAUtils.string2PrivateKey(sysPlugin.getAttribute("merPrivateKey"));

		Signature signature = Signature.getInstance("Sha1withRSA");
		signature.initSign(mer_privateKey);
		signature.update(signString.getBytes("UTF-8"));
		byte[] signed = signature.sign();
		String sign = Base64.encode(signed);
		log.info("sing:" + sign);

		//AES加密
		byte[] aesKeyByte = aesKey.getBytes();
		byte[] ivByte = aesIv.getBytes();
		String AESEncode = AESUts.encrypt((signString+"&signType=RAS&sign="+sign).getBytes(),aesKeyByte,ivByte);
		log.debug("AES加密后密文，AESEncode:" + AESEncode);

		//对AES_KEY使用RSA加密
		byte[] RASCipher = RSAUtils.publicEncrypt(edkString.getBytes(), org_publicKey);
		String RASCipherStr = Base64.encode(RASCipher);
		log.debug("RSA加密AES秘钥，RASCipherStr："+ RASCipherStr);
		String result = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><epay><merNo>"+params.get("merNo")+"</merNo><transCode>"+params.get("transCode")+"</transCode><orgSerNum>"+orgSerNum+"</orgSerNum><merSerNum>"+merSeNum+"</merSerNum><content>"    //0005  0006
				+ AESEncode+ "</content><edKey>"+ RASCipherStr + "</edKey></epay>";
		log.debug("报文：" + result);
		return result;
	}

	/**
	 *
	 * @param content 待验签字符串
	 * @return
	 * @throws Exception
	 */

	public Map<String, Object> verify(SysPlugin sysPlugin,String content, String aesKey, String aesIv) throws Exception{
		Map<String, Object> map = new HashMap<>();
		//银行公钥
//		String merPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkQwXhp85LVOlBfzYbkS41AUK7yW5DmJG90+eEoR1CNEYDXduSUChk9UQ73haNHaDgDKgHAEl0zzhmHEJItZNUeE4eLzwvyZc2rVrnX1+QCTHLqV1j90JxXEh7tg+xSzbsrl6rW6HZHac+fh+Len+eHYkeNdlnSRpglJajA2TnvP1hssEIsI3Lws1Fvd31u1/dA0fiE1etzsyandwvT8hDl/ZyoWLfa0aHZQXQzzFEIHnkyDtu+N1ygu4xo6Xy0S8TZ0YyTViBIXc1RkQYllNsbL78kW+WajFbLqjTXCvqOTjm3QCkgvXomlnaw6BKCEri8aU6AW9w6AK2PPz7KktNQIDAQAB";

		PublicKey mer_publicKey = RSAUtils.string2PublicKey(sysPlugin.getAttribute("orgPublicKey") );
		byte[] aseKeyByte = new byte[16];
		byte[] ivByte = new byte[16];

		aseKeyByte = aesKey.getBytes();
		//aes向量字符串
		ivByte = aesIv.getBytes();
		//AES解密之后明文
		String AESDncode = AESUts.decrypt(Base64.decode(content),aseKeyByte,ivByte);
		log.debug("AES解密之后明文，AESDncode:" + AESDncode);
		map.put("data", AESDncode);

		int dataEnd =AESDncode.lastIndexOf("&signType=");
		int signStart = AESDncode.lastIndexOf("&sign=");
		if (dataEnd<=0 || signStart<0){
			throw new CustomException("GWSPAY1001");
		}

		String data = AESDncode.substring(0, dataEnd);
		String signedStr = AESDncode.substring(signStart+6);
		//对明文字符串使用RSA验签

		Signature signature2 = Signature.getInstance("Sha1withRSA");
		signature2.initVerify(mer_publicKey);
		signature2.update(data.getBytes("UTF-8"));
		boolean verify = signature2.verify(Base64.decode(signedStr));
		log.info("验签结果:" + verify);
		map.put("verify", verify);
		return map;
	}

}